/******************************************************************************
* SVN­Version­Information:
* ­­­­­­­­­­­­­­­­­­­­­­­­---------------------
* $LastChangedRevision: 6 $
* $LastChangedBy: c.a.duevel $
* $LastChangedDate: 2009-08-26 15:12:37 +0000 (Wed, 26 Aug 2009) $
* $HeadURL: http://robofight.googlecode.com/svn/trunk/ClientJavaFX/src/de/hft_stuttgart/robofight/client/javafx/Arena.fx $
******************************************************************************/

package de.hft_stuttgart.robofight.client.javafx;


import de.hft_stuttgart.robofight.client.java.JPlayer;
import de.hft_stuttgart.robofight.client.java.JRobot;
import de.hft_stuttgart.robofight.client.java.JRunningGame;
import de.hft_stuttgart.robofight.client.javafx.Constants;
import de.hft_stuttgart.robofight.client.javafx.RobotNode;
import de.hft_stuttgart.robofight.client.javafx.util.*;
import java.lang.Object;
import java.util.Map.*;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.transition.FadeTransition;
import javafx.animation.transition.ScaleTransition;
import javafx.animation.transition.SequentialTransition;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.control.TextBox;

import de.hft_stuttgart.botwar.common.commands.ChatCmd;
import javafx.scene.control.Label;


import javafx.scene.control.Button;

import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;



/**
 * @author ralf.dauenhauer@gmx.de, michael.rieker@web.de
 */

public class Arena extends CustomNode {
    package var getNodeByName : function(nodeName : String) : Node;
    package var switchNode : function(className : String) : Void;
    package var playSoundByName : function(soundName : String) : Void;
    package var getPlayer : function() : JPlayer;
    package var robotNodes : java.util.Map;
    package var activeRobotId : Integer = 999 on replace oldValue{
        (robotNodes.get(oldValue) as RobotNode).isActive = false;
    };
    var robotMap : java.util.Map;
    var runningGame : JRunningGame;
    var map : Node;

    public var chatList : java.util.List;


   // check chat messages and synchronize the robots
   var time :Timeline = Timeline {
       repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time : 1000ms
                canSkip : true
                action: function() {
                    if(runningGame.getGameOverCommand() == null){
                        runningGame.checkCommand();
                        synchronizeRobot();
                        refreshChat();
                    } else {
                        gameOver();
                    }
                }
            }
        ]
    }

    function gameOver(){
        time.stop();
        getPlayer().setPolling(true);
        switchNode("GameResults");
    }

    // synchronizes the robot coordinates
    function synchronizeRobot(){
        for (entry : Object in robotMap.entrySet()){
            var jRobot = (entry as Entry).getValue() as JRobot;
            (robotNodes.get((entry as Entry).getKey()) as RobotNode).moveRobotTo(
                jRobot.getPos().getX() as Number,
                jRobot.getPos().getY() as Number);
            (robotNodes.get((entry as Entry).getKey()) as RobotNode).setEnergy(jRobot.getHealth());
            if(jRobot.isShooting()){
                 (robotNodes.get((entry as Entry).getKey()) as RobotNode).shootToRobot(jRobot.getTargetRobot());
                 jRobot.setIsShooting(false);
            }
        }
    }

    function setActiveRobot(activeRobot : Integer) : Void {
        this.activeRobotId = activeRobot;
    }

    public var chatTable = TableNode {
        layoutX : 200, layoutY : 450
        scrollStepSize: -1
        w: 500
        h: 80
    }

    var chatTextBox : TextBox = TextBox {
                layoutY : 10, layoutX : 300
                width: 250
                text: ""
                font: Constants.FONT_TEXTFIELD
                skin: Constants.getTextBoxSkin()
                onKeyPressed: function(evt: KeyEvent): Void {
                     if (evt.code == KeyCode.VK_ENTER) {
                        sendChatMsg();
                     }
                }
    }

    var toolBar = Group {
        layoutY : 550
        content: [
            Rectangle {
                width: 800, height: 50
                fill: Color.BLACK
            },
            Button {
                layoutX : 40, layoutY : 10
                text: "Aggressive"
                width: 100
                height : 30
                font : Constants.FONT_TEXTFIELD
                action: function() {
                    if(activeRobotId != 999){
                         runningGame.setMode(activeRobotId, 0);
                    }
                }
                skin: Constants.getButtonSkin()
            },
            Button {
                layoutX : 160, layoutY : 10
                text: "Defensive"
                width: 100
                height : 30
                font : Constants.FONT_TEXTFIELD
                action: function() { 
                     if(activeRobotId != 999){
                         runningGame.setMode(activeRobotId, 1);
                    }
                }
                skin: Constants.getButtonSkin()
            }
            Label {
                layoutY : 13, layoutX: 270
                text: "Chat"
                font: Constants.FONT_TEXTFIELD
            }          
            chatTextBox,
            Button {
                layoutY : 10, layoutX : 560
                text: "send"
                height : 30
                font: Constants.FONT_TEXTFIELD
                skin: Constants.getButtonSkin()
                action: function() {
                    sendChatMsg();
                 }
            }
        ]
    }

    var playerList = Group {
        layoutX : 730 layoutY : 50
        content : [];
    }

    package var group : Group = Group {
            content: [
                 Group {
                    content : bind map
                    onMouseClicked: function( e: MouseEvent ):Void {
                        if(this.activeRobotId!=999 and e.y <= 550){
                            if(not runningGame.setTarget(activeRobotId , e.x as Integer, e.y as Integer)){
                                activeRobotId = 999;
                            }
                        }
                        if (e.y <= 550){
                            animateMouseClick(e.x, e.y);
                        }

                    }
                 },
                 toolBar,
                 playerList,
                 chatTable
            ]
    };

 /**
  * initialize the game, get all Robots and the MapName
  * and insert them as Nodes into this.group
  */
  init{
      runningGame = getPlayer().getRunningGame();
      runningGame.initGame();
      robotMap = runningGame.getRobots();
      robotNodes = new java.util.HashMap();
      map = getNodeByName(runningGame.getMapName());
      // iterate over the PlayerMap and create a Playerlist with the PlayerColours
      var i = 0;
      for(entry : Object in runningGame.getPlayerMap().entrySet()){
          insert Text {
              content : (entry as Entry).getKey() as String;
              font : Constants.FONT_TEXTFIELD
              fill : Constants.colors[(entry as Entry).getValue() as Integer]
              layoutY : 20 * i;
          } into playerList.content;
          i++;
      }


      // iterate over all entries in the robotMap<robotID, JRobot> and
      // push each entry into a robotNode map<robotID, RobotNode>
      for (entry : Object in robotMap.entrySet()) {
           var botID = (entry as Entry).getKey() as Integer;
           var bot = (entry as Entry).getValue() as JRobot;
           robotNodes.put(botID, RobotNode {
               robotId : botID;
               xCoord : bot.getPos().getX();
               yCoord : bot.getPos().getY();
               robotColorId: bot.getColor();
               chassis : getNodeByName(bot.getChassisName())
               shield : getNodeByName(bot.getShieldName())
               weapon : getNodeByName(bot.getWeaponName())
               weaponBullet : getNodeByName("{bot.getWeaponName()}_Shoot");
               weaponSound: bot.getWeaponName()
               deadBot: getNodeByName("botDied");
               arena: this;
               setActive : setActiveRobot;
               }
           );
           (robotNodes.get(botID) as RobotNode).setEnergy(100 as Double);
      }
      // iterate over all entries in the robotNodes map and insert each entry
      // into this.group.content
      for (entry : Object in robotNodes.entrySet()) {
           insert (entry as Entry).getValue() as RobotNode into this.group.content;
      }
      getPlayer().setReady();
      time.play();
      toolBar.toFront();
      chatTable.toFront();
      playerList.toFront();
  }

  override function create() : Node {
      return group;
  }

  var circ;
  function animateMouseClick(x : Integer, y : Integer){
         circ = Circle {
            centerX: x, centerY:y
            radius: 8
            stroke: Color.LIGHTGREEN
            strokeDashArray : [3,4];
            fill : null
        }
        insert circ into this.group.content;
        SequentialTransition {
            node: circ
            content : [
                ScaleTransition {
                    duration: 300ms
                    byX: 3
                    byY: 3
                    repeatCount: 2
                    autoReverse: false
                },
                FadeTransition {
                    duration: 500ms
                    fromValue: 1.0
                    toValue: 0.0
                    repeatCount:1
                    autoReverse: false
                }
            ]}.play();
     }

    function refreshChat(){
        chatList = runningGame.getGameLobbyChatMsg();
        var cnt = 0;
        var yPos : Number = 12;
        if(chatList.size() > chatTable.tableEntries.size()){
            chatTable.tableEntries = null;
            while (cnt < chatList.size()){
                var message : ChatCmd;
                message = chatList.get(cnt) as ChatCmd;
                insert Text {
                    content: "{message.getChatSender() as String}: {message.getChatMessage() as String}";
                    font: Constants.FONT_CHAT
                    fill: Color.RED
                    layoutY: yPos
                } into chatTable.tableEntries;
                yPos += 12;
                cnt++;
            }
            if(chatTable.tableEntries.size()>5){
                chatTable.scrollUp();
            }
        }
    }

    function sendChatMsg(){
        runningGame.sendGameChatMessage({chatTextBox.text} as String);
        chatTextBox.text = "";
    }
}